  \chapter*{ShaderMan}
  

 Когда-то очень-очень давно, когда деревья были
    высокими, а в prman ещё не встроили raytracing, я поймал себя на
    мысли, что в процессе написания шейдеров на SL всё время повторяю
    одни и те же шаги и постоянно использую одни и те же куски кода в
    качестве образцов. Более того, у меня скопилась целая библиотека
    таких кусков и готовых шейдеров, на которых я тренировался и
    учился,  изучая чужой
    код и воплощённые в жизнь идеи (эта библиотека существует по сей
    день; в ней 685 файлов и у меня сложилось впечатление, что в
    некоторые из них я ещё ни разу не смотрел). Так вот, я начал
    подумывать о том, чтобы каким-то образом автоматизировать свою
    работу, написав специальную программу, упрощающую создание шейдеров
    – но я не был уверен в том, как должна работать такая программа, на
    какие принципы опираться и какой визуальный интерфейс является
    наиболее удобным и быстрым.
  

 Примерно в это же время появился новый продукт
    комнании (тогда ещё) Softimage под названием XSI, в котором похожая
    идея с визуальным редактированием материалов была воплощена в
    Render Tree – и после первого же скриншота я понял, в каком
    направлении мне следует двигаться.
  

 Как автор программы, я  могу долго (подозреваю, что очень
    и очень долго, но проверять не рискну) философствовать о том, какие
    идеи заложены в её основу, как именно используется та или иная
    функция, в чём смысл всего происходящего и почему аборигены съели
    Кука. Но вместо этого – давайте попробуем сделать простой шейдер и
    при этом сэкономить на типографской краске и обойтись минимумом
    скриншотов.
  

 Запускаем ShaderMan. В окошке Welcome, если вы его
    не закрыли и не отключили, выбираем кнопку Start New Shader; если
    всё-таки закрыли – то выбираем из меню File=>New… Имя шейдера по
    умолчанию (defaultname0) вполне подойдёт.
  

 В рабочей области программы появился небольшой
    элемент – в терминологии ShaderMan он называется кирпичиком
    (brick).
  

 \gr{image095}
  

 Аналогия простая – из таких вот кирпичей мы
    собираемся построить нечто полезное и красивое. С версией 0.7.0.0
    программы поставляется 345 различных кирпичиков – вполне
    естественно, что выводить их все простым списком было бы глупо и
    некрасиво по отношению к пользователю, поэтому все элементы
    рассортированы по тематическим подгруппам – которые вы и видите в
    окне слева в виде дерева (или по правому клику на свободном
    пространстве в окне ShaderMan – в виде меню).
  

 Для
    любознательных: эта древовидная
    структура всего-лишь повторяет структуру поддиректорий /brick/. Все
    брики являются файлами в формате XML с расширением – никогда не
    угадаете - *.br. Раз уж вы это читаете, а я это пишу – XML читается
    как ИГЗЭМ{\bf ЭЛЬ.}
  

 Чтобы добавить новый элемент в наш шейдер, можно
    воспользоваться левым деревом (и перетянуть-бросить – в смысле
    драг’н’дропнуть - необходимые элементы из него), контекстным меню
    рабочего стола или главным меню программы. Не суть важно, как –
    добавим несколько бриков. Какие?
  

 В первую очередь (поскольку мы не экстремалы, а
    всего-лишь начинающие шейдерописатели), это будет готовый шейдер
    (папка ready shaders) или готовая модель освещения (shading
    models). Впоследствии вы сможете сами строить новые модели
    освещения, пользуясь бриками более низкого уровня – предоставляется
    и такая возможность – а пока возьмём на вооружение уже готовые
    наработки и добавим в шейдер кирпичик OrenNayar.
  

  \gr{image097}
  

 Для
    любознательных: в наборе есть и
    стандартные для Maya lamber и blinn, но мы специально используем
    модель освещения Орена и Найара. Названная так в честь своих
    авторов, данная модель является логическим продолжением широко
    известной модели Ламберта и часто применяется при имитации
    различных тканей.
  

 Через контекстное меню переводим оба брика в режим
    с локальными изображениями (Show local preview) и, если у вас
    правильно настроен рендерер – видим нечто подобное:
  

 \gr{image099}
  

 Что-то явно не так в Датском Королевстве – все
    элементы на месте, но элемент Surface – чёрный, а элемент OrenNayar
    – показывает образец шейдера. Вывод логичен – необходимо
    подсоединить выход из одного брика к входу из другого, что мы
    мышкой и делаем, после чего сразу же тыкаем в картинку на
    Surface:
  

 \gr{image101}
  

 Вот, собственно, и всё. Окинем взглядом имеющуюся
    диспозицию:
  

 \gr{image103}
  

 В правом верхнем углу окна имеем специальную
    область просмотра результатов рендеринга. Достаточно выбрать мышкой
    из списка чего-нибудь нешарообразное, например, чайник (teapot) и
    кликнуть в эту область – и сразу появится большое превью, с которым
    можно делать всякие разности, например, смотреть по каналам RGB или
    установить рендеринг не всей картинки, а только её части – в общем,
    имеется в наличии некий мутант, собранный из возможностей fcheck,
    it и других просмотрщиков.
  

 Для
    продвинутых: для того, чтобы prman
    мог рендерить сразу в окно ShaderMan, мне пришлось написать
    специальный display driver, который затем переписывался ещё не раз,
    в том числе полностью – для Entropy, которая не поддерживала
    стандартные драйвера дисплея.
  

 \gr{image105}
  

 Внизу под областью просмотра у нас – набор
    параметров шейдера, настройки для preview и специальные редакторы
    для RIB-кода (некий аналог RIBbox из MTOR). В самом низу окна –
    консоль, в которую рендереры выводят статусную информацию – иногда
    полезно поглядывать в это окошко, чтобы вовремя обнаружить
    возможные ошибки при рендеринге.
  

 А мы тем временем через меню View отключаем все эти
    навороты и остаёмся с голым рабочим столом программы. При помощи
    контекстное меню добавляем новый брик – fractal/fractal.
    Присоединяем его выход к входу Kd OrenNayar – кстати, о Kd. Везде,
    где только можно было, я старался придерживаться стандартных имён
    параметров шейдеров, которые приняты на практике, например, Kd –
    это коэффициент диффузии. Но в определённый момент столкнувшись с
    вопросами новичков, в особенности пришедших из Maya HyperShade, я
    придумал опцию View => Friendly Shader Parameters, которая даёт
    параметрам шейдеров более дружественные и понятные
    имена:
  

 \gr{image107}
  

 Кроме визуального, а ля HyperShade, режима
    редактирования шейдеров в ShaderMan реализован ещё один
    режим, a la Slim. Дабл-кликните (это в смысле - дважды) на любом брике,
    например, на достославном Oren-Nayar:
  

 \gr{image109}
  

 Далее всё работает почти как в Slim – прямо из
    этого окна можно присоединять новые элементы, смотреть на
    результаты на различных стадиях – в общем, каждый выбирает свой
    метод редактирования шейдера.
  

 Каким образом результат нашей работы можно
    использовать в Maya? Собственно в Maya – почти никак, потому что
    конечным результатом работы в ShaderMan является шейдер SL. Кроме
    этого, вы можете экспортировать темплейты Slim - и уже их
    непосредственно подключать к MTOR – либо специальные файлы для
    Liquid – и использовать их. Ну и наконец, можно отрендерить шейдер
    в текстуру, которую затем подсасывать в майские шейдеры.
  

 На этой мажорной ноте придётся оборвать наше
    повествование. Я много чего  не рассказал вам о ShaderMan.
    Например, о маркинговом меню (идея которого, которую я впервые
    увидел в продуктах Alias, поразила меня до глубины души). Или о
    потенциальной расширяемости программы, основанной на простом
    структурированом текстовом формате XML (запомнили? {\it ИГЗЭМЭЛЬ!}) и усиленной языком
    программирования Tcl. Или о встроенной поддержке более чем десятка
    Renderman-совместимых рендереров – и лёгком добавлении новых (ещё
    раз повторяем волшебное слово – правильно, XML). Или о
    дружественности продукта для новичков и одновременной мощности для
    опытных (я тоже раньше думал, что это почти нереально). Или про –
    о, вспомнил. О пункте меню File=> Import.
  

 Найдите на диске один из шейдеров, с которыми мы
    экспериментировали раньше, например, textured\_noise.sl:
  

surface
    textured\_noise ( float freq=100; )
  

{
  

  Ci = texture("texture.tx", s,
    t)*noise(freq*s,freq*t);
  

 }
  

 Вызываем из главного меню ShaderMan
    File=>Import=>Shader source as new brick…, выбираем только
    что найденный нами файл и через несколько секунд (в течение которых
    запускается и выполняется конвертер из шейдера SL в формат брика
    BR) на рабочем столе ShaderMan появляется новый брик –
    textured\_noise. Присоединяем его к Surface Color кирпичика
    Oren-Nayar и немедленно получаем:
  

 \gr{image111}
  

 Таким образом мы можем загрузить в виде нового
    брика практически любой готовый шейдер, написанный на языке
    Renderman SL, и в дальнейшем использовать его как часть своих
    собственных шейдеров. Но это ещё не всё. В том же меню ShaderMan
    File=>Import выбираем другой подпункт – RIB file as template.
    Находим нашего первенца, test1.rib – тот самый, неосвещённый с
    единственным одиноким полигоном перпендикулярно камере:
  

Display
    "RenderMan" "framebuffer" "rgb"
  

Format
    256 192 -1
  

ShadingRate
    1
  

WorldBegin
  

   Surface "plastic"
  

   Polygon "P" [0.5 0.5 0.5 0.5 -0.5 0.5 -0.5
    -0.5
  

                 0.5 -0.5 0.5 0.5]
  

 WorldEnd
  

 Пока не случилось непоправимое, быстренько
    открывает этот файл в тектовом редакторе, вспоминаем, чему мы
    учились всю эту главу, и добавляем источники света (для ленивых или
    тех, кто читает книжку, сидя в метро – файл
    test\_shaderman.rib):
  

Display
    "RenderMan" "framebuffer" "rgb"
  

Format
    256 192 -1
  

ShadingRate
    1
  

WorldBegin
  

     LightSource "ambientlight" 500
  

                 "lightcolor" [0.051 0.051 0.051]
  

     LightSource "distantlight" 501 "from" [1
    1.5 -1] "to" [0 0 0]
  

     LightSource "distantlight" 502
    "lightcolor" [0.2 0.2 0.2]
  

                 "from" [-1.3 -1.2 -1.0] "to" [0 0 0]
  

     AttributeBegin
  

       Attribute "identifier" "name"
    ["polyShape"]
  

       Surface "plastic"
  

       Polygon "P" [0.5 0.5 0.5 0.5
    -0.5 0.5 -0.5
  

  -0.5 0.5 -0.5 0.5 0.5]
  

     AttributeEnd
  

WorldEnd
  

 Кроме источников света мы также добавили аттрибут
    “identifier”, который позволяет нам дать имя объекту – такие
    аттрибуты добавляют, в том числе, все экспортеры из Maya в RIB. И
    только теперь импортируем в ShaderMan.
  

 Для
    продвинутых: те же самые операции
    по импорту файлов можно проделать, просто перетянув их мышкой из
    Windows Explorer.
  

 Вроде бы ничего не поменялось и не произошло, кроме
    разве что сообщения в консольном окне (и строке статуса) ShaderMan
    - /rib\_example/test\_shaderman.rib : done. Для того, чтобы понять
    всю важность произошедшего, включите обратно область preview и
    попробуйте выбрать в выпадающем списке объект:
  

 \gr{image113}
  

 Мы только что загрузили внешний RIB файл в качестве
    сцены для использования в ShaderMan – и программа предоставила нам
    возможность выбрать объект, на котором мы будем тестировать наш
    шейдер (не случайно мы дали нашему объекту имя).
  

 Попробуем проиллюстрировать все эти возможности,
    модицифировав диаграмму передачи данных и файлов в рамках RAT.
    Стоит обратить внимание на то, что некоторые стрелочки в схеме –
    двунаправленные; это означает, например, что ShaderMan может как
    экспортировать, так и импортировать файлы SL.
  

 \gr{image115}
  

 Название ShaderMan появилось не сразу. Первые
    публичные релизы программы (а раздавал я их сначала только
    русскоязычным пользователям) назывались TheTool – собственно,
    веб-страница продукта до сих пор носит такое название -
    http://www.dream.com.ua/thetool.html. И идея с новым названием и
    вообще выкладыванием своего творения на публику тоже пришла не
    сразу – изначально это был внутренний проект, программа для себя,
    чтобы сделать свою работу интереснее и проще. Лишь потом, получив
    много полезных и приятных откликов от первых пользователей
    ShaderMan’а, я озаботился всем тем, что отличает нормальную
    программу от кустарной поделки – написанием помощи, созданием
    нормальной веб-страницы, инфраструктурой для поддержки
    пользователей. И ещё – именно из-за того самого первого фидбэка
    программа осталась бесплатной. В конце концов, всё, что мне было
    нужно от своего детища – это получить инструмент для дальнейших
    исследований и получить удовольствие от самого процесса написания
    программы. И если ShaderMan оказался полезен не только для меня, но
    и для (многочисленных, насколько я могу судить по количеству
    скачиваний) пользователей – это очень приятно.
  

 Ведь так?
